use std::sync::atomic::{AtomicI64, Ordering};

use axum::{routing::{get, post}, Router};

use crate::{error::AppErr, serve::conn::{cbor_ok, online::ONLINE_INFO, Cbor, CborRet, Void}, store::vote::{self, Vote}};

static VOTE_ID: AtomicI64 = AtomicI64::new(1);

async fn on_get_current_id() -> CborRet<i64> {
    cbor_ok(VOTE_ID.load(Ordering::Relaxed))
}

async fn on_set_current_id(id: Cbor<i64>) -> Result<Void, AppErr> {
    VOTE_ID.store(id.0, Ordering::Relaxed);
    ONLINE_INFO.notify();
    Ok(Void)
}

async fn on_get_latest_id() -> CborRet<i64> {
    let id = vote::latest_id().await?;
    cbor_ok(id)
}

async fn on_create(name: Cbor<String>) -> Result<Void, AppErr> {
    vote::create(&name.0).await?;
    ONLINE_INFO.notify();
    Ok(Void)
}

async fn on_delete(id: Cbor<i64>) -> Result<Void, AppErr> {
    vote::delete(id.0).await?;
    ONLINE_INFO.notify();
    Ok(Void)
}

async fn on_query() -> CborRet<Vec<Vote>> {
    let votes = vote::query().await?;
    cbor_ok(votes)
}

pub fn register() -> Router {
    Router::new()
    .route("/create", post(on_create))
    .route("/latest_id", get(on_get_latest_id))
    .route("/delete", post(on_delete))
    .route("/query", get(on_query))
    .route("/current_id", get(on_get_current_id))
    .route("/set_current", post(on_set_current_id))
}

